-- ======================================================================
-- Hell Logic Sniffer Addon 
-- 
-- Copyright 2013 Hell-Prototypes
--
-- http://www.hellprototypes.com/
-- ======================================================================

ModuleClass = "LS_PLUGIN"
ModuleName  = "PeriodNumber"
ModuleTip   = "Calculate the period number within two cursor"

g_sampling_period = -1
g_left_cursor_index = -1
g_right_cursor_index = -1
g_curr_ch_num = -1

g_ch_data = {}

function read_param_value(_LS_API)
	param = _LS_API.GetCommonParameter()
	if #param < 4 then
		_LS_API.MessageBox("<PeriodNumber> Error param : table size : " .. #param)
		return false
	end
	g_sampling_period = param[1]
	g_left_cursor_index = param[2]
	g_right_cursor_index = param[3]
	g_curr_ch_num = param[4]
	
	if g_sampling_period < 10 then
		_LS_API.MessageBox("<PeriodNumber> Error param : Sampling period : " .. g_sampling_period)
		return false
	end
	
	if g_left_cursor_index < 0 then
		_LS_API.MessageBox("<PeriodNumber> Error param : Left cursor index : " .. g_left_cursor_index)
		return false
	end
	
	if g_right_cursor_index < 0 then
		_LS_API.MessageBox("<PeriodNumber> Error param : Right cursor index : " .. g_right_cursor_index)
		return false
	end

	if g_curr_ch_num > 15 or g_curr_ch_num < 0 then
		_LS_API.MessageBox("<PeriodNumber> Error param : Current channel number : " .. g_curr_ch_num)
		return false
	end
	
	return true
end

function get_param()
	local table = {}
	
	if g_sampling_period * g_left_cursor_index * g_right_cursor_index * g_curr_ch_num < 0 then
		return nil
	end

	table[1] = g_sampling_period
	table[2] = g_left_cursor_index
	table[3] = g_right_cursor_index
	table[4] = g_curr_ch_num

	return table
end

function get_period_number (__LS_API)
	if not read_param_value(__LS_API) then
		return -1
	end
	__LS_API.DebugMsg("Get param succ")
	
	__LS_API.DebugMsg("g_sampling_period = " .. g_sampling_period)
	__LS_API.DebugMsg("g_left_cursor_index = " .. g_left_cursor_index)
	__LS_API.DebugMsg("g_right_cursor_index = " .. g_right_cursor_index)
	__LS_API.DebugMsg("g_curr_ch_num = " .. g_curr_ch_num)

    g_ch_data = __LS_API.GetChannelData(g_curr_ch_num)
    if #g_ch_data == 0 then
	    __LS_API.MessageBox("<PeriodNumber> No data on select channel")
		return -2
	end

	if g_left_cursor_index > g_right_cursor_index then
		local temp = g_left_cursor_index
		g_left_cursor_index = g_right_cursor_index
		g_right_cursor_index = temp
	end

	local rawdata_index = 3
	local failling_edge_count = 0

	-- Find left edge
	while rawdata_index <= #g_ch_data do
		if g_ch_data[rawdata_index] > g_left_cursor_index then
			break
		end
		rawdata_index = rawdata_index + 2
	end
	-- Count failling edge
	while rawdata_index <= #g_ch_data do
		if g_ch_data[rawdata_index] >= g_right_cursor_index then
			break
		end
		if g_ch_data[rawdata_index+1] == 0 then
			failling_edge_count = failling_edge_count + 1
		end
		rawdata_index = rawdata_index + 2
	end
	
	return failling_edge_count
end

function main()
	local count = get_period_number(LS_API)

	if count < 0 then
		LS_API.MessageBox("<PeriodNumber> Error on find edge")
		return
	end

	LS_API.ReportPushBack("")
	LS_API.ReportPushBack("= PeriodNumber Plugin Report:=====================")
	LS_API.ReportPushBack("= Period Number = " .. count)
	LS_API.ReportPushBack("==================================================")
end

-- Export function
local MOD = {}
MOD.get_period_number = get_period_number
MOD.get_param = get_param
MOD.get_period_number = get_period_number

return MOD